package GUI;

import domain.DomainController;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
 * This class represents the user interface of HTTPDragon.
 * @author HTTPDragon Team
 */
public class DragonGUI extends javax.swing.JFrame implements Observer {
    // op deze manier haalt java de images enkel bij opstarten 1 keer op, ipv elke keer server status change
    private Icon dragonAwake = new javax.swing.ImageIcon(getClass().getResource("/GUI/resources/Dragon.png"));
    private Icon dragonAsleep = new javax.swing.ImageIcon(getClass().getResource("/GUI/resources/DragonStopped.png"));
    private boolean isShowingPopup = false;
    private static DomainController dc;

    /**
     * Creates new form DragonGUI.
     * @param dc DomainController instance
     */
    public DragonGUI(final DomainController dc) {
        this.dc = dc;
        dc.addObserver(this); 
        this.setIconImage(new ImageIcon(getClass().getResource("/GUI/resources/Dragon.png")).getImage());
        initComponents();
        this.setLocationRelativeTo(null);
        setVisible(true);  
//        updateAll();
    }
    
    /**
     * Updates the user interface 
     */
    private void updateAll(){       
        updateMenu();
        updateStatusText();
    }
    
    /**
     * This method updates the user interface when the server status is changed.
     */
    private void updateMenu(){
        if(dc.serverStatusBoolean()){ 
             btnMenu.setIcon(dragonAwake);   
            itemStart.setEnabled(false);         
            itemStop.setEnabled(true);           
            itemRestart.setEnabled(true);            
        }else{        
            btnMenu.setIcon(dragonAsleep); 
            itemStart.setEnabled(true);        
            itemStop.setEnabled(false);      
            itemRestart.setEnabled(false);        
        }
    }
        
    /**
     * This method updates the status text when called.
     */
    private void updateStatusText(){
        lblStatus.setText(dc.serverStatus());
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        popupMenu = new javax.swing.JPopupMenu();
        controlMenu = new javax.swing.JMenu();
        itemStart = new javax.swing.JMenuItem();
        itemStop = new javax.swing.JMenuItem();
        itemRestart = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        itemOpenConfig = new javax.swing.JMenuItem();
        txtLogger = new java.awt.TextArea();
        lblStatus = new javax.swing.JLabel();
        lblDragon = new javax.swing.JLabel();
        btnMenu = new javax.swing.JButton();

        controlMenu.setText("HTTPDragon");

        itemStart.setText("Start");
        itemStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemStartActionPerformed(evt);
            }
        });
        controlMenu.add(itemStart);
        itemStart.getAccessibleContext().setAccessibleDescription("");

        itemStop.setText("Stop");
        itemStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemStopActionPerformed(evt);
            }
        });
        controlMenu.add(itemStop);

        itemRestart.setText("Restart");
        itemRestart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemRestartActionPerformed(evt);
            }
        });
        controlMenu.add(itemRestart);

        popupMenu.add(controlMenu);
        popupMenu.add(jSeparator1);

        itemOpenConfig.setLabel("Configuration");
        itemOpenConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemOpenConfigActionPerformed(evt);
            }
        });
        popupMenu.add(itemOpenConfig);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("HTTPDragon");
        setResizable(false);

        txtLogger.setEditable(false);
        txtLogger.setName(""); // NOI18N

        lblStatus.setText("");
        lblStatus.setToolTipText("Current server status.");

        lblDragon.setFont(new java.awt.Font("Tahoma", 1, 11));
        lblDragon.setText("Dragon health:");

        btnMenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/GUI/resources/Dragon.png"))); // NOI18N
        btnMenu.setAutoscrolls(true);
        popupMenu.addFocusListener(new FocusListener(){
            @Override
            public void focusLost(FocusEvent e){
                isShowingPopup = false;
            }
            public void focusGained(FocusEvent e){
                isShowingPopup = true;
            }
        });

        popupMenu.addComponentListener(new ComponentListener() {
            @Override
            public void componentShown(ComponentEvent e) {

            }

            @Override
            public void componentResized(ComponentEvent e) {

            }

            @Override
            public void componentMoved(ComponentEvent e) {

            }

            @Override
            public void componentHidden(ComponentEvent e) {

            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtLogger, javax.swing.GroupLayout.PREFERRED_SIZE, 450, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnMenu, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblDragon)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(lblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btnMenu, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(lblStatus)
                        .addComponent(lblDragon)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtLogger, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        btnMenu.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isShowingPopup) {
                    popupMenu.requestFocus();
                } else {
                    Component c = (Component) e.getSource();
                    popupMenu.show(c, -1, c.getHeight());
                }
            }
        });

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * Starts the server and repaints the user interface.
     * @param evt ActionEvent
     */
private void itemStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemStartActionPerformed
    dc.serverStart();     
}//GEN-LAST:event_itemStartActionPerformed
    /**
     * Stops the server and repaints the user interface.
     * @param evt ActionEvent
     */
private void itemStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemStopActionPerformed
    dc.serverStop();
}//GEN-LAST:event_itemStopActionPerformed
    /**
     * Restarts the server and repaints the user interface.
     * @param evt ActionEvent
     */
private void itemRestartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemRestartActionPerformed
    dc.serverRestart();
}//GEN-LAST:event_itemRestartActionPerformed
    /**
     * Write to the logger and shows it on the screen.
     * @param message A message you wish to show.
     */
    public static void appendLog(String message){    
        //TODO: limit on amount of messages displayed
        txtLogger.append(message +"\n");      
    }
    /**
     * Opens the 'config.xml' file in an environment's default text editor.
     * @param evt ActionEvent
     */
    private void itemOpenConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemOpenConfigActionPerformed
      try{
          File config = dc.getConfigFile();
          if (config.exists() && config.length()>0 ){
              Desktop desktop = null;
              if (Desktop.isDesktopSupported()){
                  desktop = Desktop.getDesktop();
                  desktop.edit(config);
              }
          }          
      }catch (IOException iOException){
              iOException.printStackTrace();
      }
    }//GEN-LAST:event_itemOpenConfigActionPerformed

    // Variables declaration
    private javax.swing.JButton btnMenu;
    private javax.swing.JMenu controlMenu;
    private javax.swing.JMenuItem itemOpenConfig;
    private javax.swing.JMenuItem itemRestart;
    private javax.swing.JMenuItem itemStart;
    private javax.swing.JMenuItem itemStop;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JLabel lblDragon;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JPopupMenu popupMenu;
    private static java.awt.TextArea txtLogger;
    // End of variables declaration
    
     /**
     * This method updates the JFrame when the server(s) changed state 
     * @param o DomainController
     * @param arg Arguments to pass
     */
    @Override
    public void update(Observable o, Object arg) {
        updateAll();
        repaint();
    }

}
